<template>
  <el-cascader
    v-model="addrValue"
    :placeholder="requestOneAddressLoading ? '正在填充地址' : '请选择地址'"
    :props="addressProps"
    :options="addrOptions"
    @change="onChange"
    filterable
    :disabled="requestOneAddressLoading"
    clearable
    collapse-tags
    collapse-tags-tooltip
  ></el-cascader>
</template>

<script setup lang="ts" name="singleAddress">
import { ref, onBeforeMount, watch, defineProps, defineExpose } from 'vue'
import type { CascaderProps } from 'element-plus'
import { getPrimaryAddress } from '@/api/address' // 引入你的地址接口

// 接收父组件传递的地址和配置
const prop = defineProps({
  address: {
    type: Object,
    default: () => ({
      province: '',
      city: '',
      area: '',
      town: '',
      SelectType: true, // 默认多选
    }),
  },
  checkStrictly: {
    type: Boolean,
    default: false,
  },
})

// 组件内部状态
const emit = defineEmits<{
  (e: 'value-change'): void
  (e: 'clear'): void
}>()
const addrValue = ref<string[]>([]) // 选中的地址编码路径
const addrOptions = ref<AddressOption[]>([]) // 地址选项数据
const requestOneAddressLoading = ref(false) // 加载状态
const hasAddrSource = ref(false) // 是否有地址源
const hasEchoAddr = ref(false) // 是否有回显地址
const selectAddr = ref({
  province: '', // 省
  city: '', // 市
  area: '', // 县/区
  town: '', // 镇
})

// 地址配置项
const addressProps: CascaderProps = {
  value: 'code', // 唯一标识字段
  label: 'name', // 显示名称字段
  children: 'children', // 子级字段
  expandTrigger: 'click', // 展开方式
  // checkStrictly: prop.checkStrictly, // 严格模式
  multiple: prop.address.SelectType, // 多选模式（父组件控制）
}

// 地址选项数据结构（根据实际接口调整）
interface AddressOption {
  code: string
  name: string
  children?: AddressOption[]
}

// 地址点击改变事件
const onChange = (val) => {
  if (val) {
    if (prop.address.SelectType) {
      // 多选
      selectAddr.value = val.map((item) => ({
        province: item[0]?.name || '',
        city: item[1]?.name || '',
        area: item[2]?.name || '',
        town: item[3]?.name || '',
      }))
    } else {
      // 单选
      const [pCode, cCode, aCode, tCode] = val.flat()
      const addr = { province: '', city: '', area: '', town: '' }
      const provinceItem = addrOptions.value.find((item) => item.code === pCode)
      if (provinceItem) addr.province = provinceItem.name
      const cityItem = provinceItem?.children?.find((item) => item.code === cCode)
      if (cityItem) addr.city = cityItem.name
      const areaItem = cityItem?.children?.find((item) => item.code === aCode)
      if (areaItem) addr.area = areaItem.name
      const townItem = areaItem?.children?.find((item) => item.code === tCode)
      if (townItem) addr.town = townItem.name
      selectAddr.value = addr
    }
    addrValue.value = val
    emit('value-change')
  }
}

/**
 * 地址回显方法
 */
const addressEcho = () => {
  if (!prop.address.province) {
    return
  }
  hasEchoAddr.value = false
  addrValue.value = []
  addrOptions.value.map((pro) => {
    if (pro.name === prop.address.province) {
      addrValue.value.push(pro.code)
      pro.children.map((cit) => {
        if (cit.name === prop.address.city) {
          addrValue.value.push(cit.code)
          cit.children.map((area) => {
            if (area.name === prop.address.area) {
              addrValue.value.push(area.code)
            }
          })
        }
      })
    }
  })
}

// 获取一级地址
const requestOneAddressApi = async () => {
  if (prop.address.province) {
    requestOneAddressLoading.value = true
  }
  addrOptions.value = []
  const res = await getPrimaryAddress()
  addrOptions.value = res.data.data.rows
  hasAddrSource.value = true
  hasEchoAddr.value && addressEcho()
  requestOneAddressLoading.value = false
}

// 获取选中的地址对象
const getSelectAddr = () => {
  if (!addrValue.value?.length) {
    return prop.address.SelectType ? [] : {}
  }

  if (prop.address.SelectType) {
    return addrValue.value.map((valuePath) => {
      const addrObj = { province: '', city: '', area: '', town: '' }
      addrOptions.value.some((pro) => {
        if (pro.code === valuePath[0]) {
          addrObj.province = pro.name
          pro.children?.some((cit) => {
            if (cit.code === valuePath[1]) {
              addrObj.city = cit.name
              cit.children?.some((area) => {
                if (area.code === valuePath[2]) {
                  addrObj.area = area.name
                  return true
                }
              })
              return true
            }
          })
          return true
        }
      })
      return addrObj
    })
  } else {
    const [pCode, cCode, aCode, tCode] = addrValue.value.flat()
    const addr: AddressObject = { province: '', city: '', area: '', town: '' }
    const provinceItem = addrOptions.value.find((item) => item.code === pCode)
    if (provinceItem) addr.province = provinceItem.name
    const cityItem = provinceItem?.children?.find((item) => item.code === cCode)
    if (cityItem) addr.city = cityItem.name
    const areaItem = cityItem?.children?.find((item) => item.code === aCode)
    if (areaItem) addr.area = areaItem.name
    const townItem = areaItem?.children?.find((item) => item.code === tCode)
    if (townItem) addr.town = townItem.name
    return addr
  }
}

// 清空选中值
const clearSelectAddr = () => {
  addrValue.value = []
  selectAddr.value = []
  emit('clear')
}

// 监听地址回显
watch(
  () => prop.address,
  () => {
    if (prop.address.province === '') {
      return
    }
    if (hasAddrSource.value) {
      addressEcho()
    } else {
      hasEchoAddr.value = true
    }
  },
  {
    immediate: true, // 加上此即可监听到第一次的值
  },
)

watch(addrValue, (value) => {
  if (!value) {
    emit('clear')
  }
})

onBeforeMount(() => {
  requestOneAddressApi()
})

defineExpose({
  getSelectAddr,
  clearSelectAddr,
})

// 地址对象类型定义
interface AddressObject {
  province: string
  city: string
  area: string
  town: string
}
</script>

<style lang="scss" >
/* 可选：调整级联选择器样式 */
.el-cascader {
  width: 100%;
}
.el-cascader__tags {
  flex-wrap: nowrap;
}
</style>    